import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

import error.processing.MyErrorProcessing;
import execution.InOutProcess;
import grammar.parser.CompUnit;
import grammar.parser.GrammarParser;
import word.parser.WordEleFactory;
import word.parser.WordElement;

public class Compiler {

    private static final String INPUT_FILE_NAME = "testfile.txt";
    private static final String ERROR_TXT = "error.txt";

    private static ArrayList<WordElement> lexicalAnalysis() {
        try {

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(INPUT_FILE_NAME)));

            WordEleFactory factory = new WordEleFactory();
            ArrayList<WordElement> elements = new ArrayList<>();
            int lineCnt = 0;
            while (true) {
                lineCnt++;
                String line = reader.readLine();
                if (line == null) {
                    break;
                }

                elements.addAll(factory.buildElements(line, lineCnt));
            }
            return elements;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("open file fail");
            throw new RuntimeException();
        }
    }

    private static CompUnit grammarAndSemanticParser(List<WordElement> wordElements) {
        GrammarParser.initGrammarParser(wordElements);
        return GrammarParser.parser();
    }

    private static TreeSet<MyErrorProcessing> errorProcessing() {
        return MyErrorProcessing.getErrors();
    }

    public static void main(String[] args) {
        try {
            FileOutputStream errorOutputStream = new FileOutputStream(ERROR_TXT);
            OutputStreamWriter writer = new OutputStreamWriter(errorOutputStream);
            List<WordElement> ans = lexicalAnalysis();
            /*for (WordElement element : ans) {
                System.out.println(element);
            }*/
            CompUnit compUnit = grammarAndSemanticParser(ans);
            TreeSet<MyErrorProcessing> errors = errorProcessing();
            for (MyErrorProcessing error : errors) {
                writer.write(error.toString());
                writer.write("\n");
                System.out.println(error);
            }
            writer.flush();
            if (errors.isEmpty()) {
                InOutProcess.init();
                compUnit.execute();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
